package com.linciping.gradle.inject.view.utils

import org.objectweb.asm.MethodVisitor

object HookUtil {

    private val targetFragmentClassMap = setOf(
        //Android App Fragment
        "android/app/Fragment",
        "android/app/ListFragment",
        "android/app/DialogFragment",
        //Support V4 Fragment
        "android/support/v4/app/Fragment",
        "android/support/v4/app/ListFragment",
        "android/support/v4/app/DialogFragment",
        //AndroidX Fragment
        "androidx/fragment/app/Fragment",
        "androidx/fragment/app/ListFragment",
        "androidx/fragment/app/DialogFragment",
        //BottomSheetDialogFragment
        "com/google/android/material/bottomsheet/BottomSheetDialogFragment"
    )

    fun isFragment(className: String): Boolean {
        return targetFragmentClassMap.contains(className)
    }

    /**
     * 加载参数，并添加方法调用
     * @param methodVisitor 当前方法操作对象
     * @param opcode 方法调用码
     * @param owner 调用方法所在类名
     * @param methodName 调用方法名
     * @param methodDesc 调用方法描述
     * @param start 加载参数对应的起点
     * @param count 加载参数数量
     * @param paramOpcodes 参数操作码
     */
    fun visitMethodWithLoadedParams(
        methodVisitor: MethodVisitor,
        opcode: Int,
        owner: String?,
        methodName: String?,
        methodDesc: String?,
        start: Int,
        count: Int,
        paramOpcodes: List<Int>
    ) {
        for (i in start until start + count) {
            methodVisitor.visitVarInsn(paramOpcodes[i - start], i)
        }
        methodVisitor.visitMethodInsn(opcode, owner, methodName, methodDesc, false)
    }
}